﻿using System;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Net;
using System.Security.Cryptography;
using System.Security.Policy;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Forms;
using System.Windows.Media;
using Ionic.Utils;
using OpenFileDialog = Microsoft.Win32.OpenFileDialog;

namespace MovieBuddy.Controls
{
    /// <summary>
    /// Interaction logic for FilePicker.xaml
    /// </summary>
    public partial class FilePicker
    {
        private Uri lastUri;
        private string extensions;
        private string typeDescription;


        public FilePicker()
        {
            InitializeComponent();
        }
        


        public bool IsForImages { get; set; }
        public bool IsForFolders { get; set; }

        public bool AllowUrl { get; set; }

        /// <summary>
        /// sets the default extensions to allow for the file picker.
        /// </summary>
        /// <param name="description">a description of the type of files (i.e. "Video Files")</param>
        /// <param name="fileExtensions">a semicolon delimited list of extensions. (*.iso;*.avi;*.mpg)</param>
        public void SetExtensions(string description, string fileExtensions)
        {
            typeDescription = description;
            extensions = fileExtensions;
        }

        private void BrowseClick(object sender, RoutedEventArgs e)
        {
            if (IsForFolders)
            {
                var folderDialog = new FolderBrowserDialogEx();
                if (folderDialog.ShowDialog() == DialogResult.OK)
                {
                    textBox.Text = folderDialog.SelectedPath;
                }
                return;
            }

            var dialog = new OpenFileDialog();

            if (IsForImages)
            {
                extensions = String.Join("; ", ImageCodecInfo.GetImageEncoders().Select(enc => enc.FilenameExtension));
                typeDescription = "Image Files";

            }
            if (!string.IsNullOrEmpty(extensions))
            {
                dialog.Filter = typeDescription + "(" + extensions + ") | " + extensions + " | All Files | *.*";
            }
            if (dialog.ShowDialog(Window.GetWindow(this)) == true)
            {
                textBox.Text = dialog.FileName;
            }
        }

        private void TextChangedHandler(object sender, TextChangedEventArgs e)
        {

            Func<string, bool> checker = File.Exists;
            if (IsForFolders) checker = Directory.Exists;
            if (AllowUrl)
            {
                var innerChecker = checker;
                checker = url =>
                {
                    try
                    {
                        var client = new WebClient();
                        var webUri = new Uri(url);
                        var webStream = client.OpenRead(webUri);
                        if (webStream == null) throw new Exception("hack"); // throw to try the file method...
                        webStream.Close();
                        return true;
                    }
// ReSharper disable once EmptyGeneralCatchClause
                    catch
                    {
                        // no-op, just move on
                    }
                    return innerChecker(url);
                };
            }

            string file = FileName;
            if (string.IsNullOrEmpty(file))
            {
                textBox.Background = Brushes.White;
                if (lastUri != null) InvokeFileUpdated(FilePickerUpdatedEventArgs.Null());
                lastUri = null;
            }
            else if (checker(textBox.Text.Trim()))
            {
                textBox.Background = Brushes.LightGreen;
                lastUri = new Uri(textBox.Text.Trim());
                var eventArgs = FilePickerUpdatedEventArgs.FromUri(lastUri);
                InvokeFileUpdated(eventArgs);
            }
            else
            {
                textBox.Background = Brushes.LightPink;
                if (lastUri != null) InvokeFileUpdated(FilePickerUpdatedEventArgs.Null());
                lastUri = null;
            }
        }

        public string FileName
        {
            get { return textBox.Text.Trim(); }
            set { textBox.Text = value; }
        }


        public event EventHandler<FilePickerUpdatedEventArgs> FileUpdated;

        public void InvokeFileUpdated(FilePickerUpdatedEventArgs e)
        {
            EventHandler<FilePickerUpdatedEventArgs> handler = FileUpdated;
            if (handler != null) handler(this, e);
        }
    }
}
